package api

import (
	"fmt"
	"log"
	"net/http"
	"strconv"
	"time"

	httpProto "internal-net-bridge-server/internal/tunnel/protocols/http"

	"github.com/gin-gonic/gin"
)

// UploadCacheHandler 上传缓存API处理器
type UploadCacheHandler struct {
	cacheManager *httpProto.UploadCacheManager
}

// NewUploadCacheHandler 创建上传缓存处理器
func NewUploadCacheHandler(cacheManager *httpProto.UploadCacheManager) *UploadCacheHandler {
	return &UploadCacheHandler{
		cacheManager: cacheManager,
	}
}

// GetCachedUpload 获取缓存的上传请求
// GET /api/upload/cache/:requestID
func (h *UploadCacheHandler) GetCachedUpload(c *gin.Context) {
	requestID := c.Param("requestID")

	log.Printf("📥 [缓存API] 客户端请求缓存: RequestID=%s", requestID[:8]+"...")

	// 从缓存获取
	upload, err := h.cacheManager.Get(requestID)
	if err != nil {
		log.Printf("❌ [缓存API] 缓存不存在: RequestID=%s, Error=%v",
			requestID[:8]+"...", err)
		c.JSON(http.StatusNotFound, gin.H{
			"error":   "缓存不存在或已过期",
			"message": err.Error(),
		})
		return
	}

	// 设置响应头 - 传递原始请求信息
	c.Header("X-Request-Method", upload.Method)
	c.Header("X-Request-Path", upload.Path)
	c.Header("X-Tunnel-ID", upload.TunnelID)
	
	// 🆕 传递chunked标记
	if upload.IsChunked {
		c.Header("X-Is-Chunked", "true")
		c.Header("X-Original-Content-Length", fmt.Sprintf("%d", upload.ContentLength))
	}

	// 复制原始请求头
	for key, value := range upload.Headers {
		// 跳过一些不需要的头
		if key == "Host" || key == "Connection" {
			continue
		}
		c.Header("X-Original-"+key, value)
	}

	log.Printf("✅ [缓存API] 返回缓存: RequestID=%s, Method=%s, Path=%s, Size=%.2f KB",
		requestID[:8]+"...", upload.Method, upload.Path,
		float64(len(upload.Body))/1024)

	// 返回Body (使用原始Content-Type)
	c.Data(http.StatusOK, upload.ContentType, upload.Body)

	// 可选: 获取后删除缓存 (节省内存)
	// h.cacheManager.Delete(requestID)
}

// GetCacheStats 获取缓存统计信息
// GET /api/upload/cache/stats
func (h *UploadCacheHandler) GetCacheStats(c *gin.Context) {
	count, totalSize := h.cacheManager.GetStats()

	c.JSON(http.StatusOK, gin.H{
		"count":     count,
		"totalSize": totalSize,
		"totalSizeMB": float64(totalSize) / (1024 * 1024),
	})
}

// DeleteCache 手动删除缓存
// DELETE /api/upload/cache/:requestID
func (h *UploadCacheHandler) DeleteCache(c *gin.Context) {
	requestID := c.Param("requestID")

	h.cacheManager.Delete(requestID)

	c.JSON(http.StatusOK, gin.H{
		"message": "缓存已删除",
	})
}

// GetChunk 获取指定分片（用于客户端分片拉取）
// GET /api/upload/cache/:requestID/chunk/:chunkIndex
func (h *UploadCacheHandler) GetChunk(c *gin.Context) {
	startTime := time.Now()
	requestID := c.Param("requestID")
	chunkIndexStr := c.Param("chunkIndex")

	chunkIndex, err := strconv.Atoi(chunkIndexStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的分片索引"})
		return
	}

	log.Printf("📥 [分片API] 开始获取: RequestID=%s, Chunk=%d, Client=%s",
		requestID[:8]+"...", chunkIndex, c.ClientIP())

	// 🚀 流式传输优化：直接从磁盘流式读取，避免一次性加载到内存
	// 获取分片数据
	readStart := time.Now()
	data, err := h.cacheManager.GetChunk(requestID, chunkIndex)
	readDuration := time.Since(readStart)
	
	if err != nil {
		log.Printf("❌ [分片API] 获取分片失败: RequestID=%s, Chunk=%d, Error=%v, 耗时=%.3fs",
			requestID[:8]+"...", chunkIndex, err, readDuration.Seconds())
		c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
		return
	}

	// 设置响应头
	c.Header("Content-Type", "application/octet-stream")
	c.Header("Content-Length", fmt.Sprintf("%d", len(data)))
	c.Header("Cache-Control", "no-cache")
	c.Header("Connection", "keep-alive")
	
	// 🚀 流式传输：分块写入，避免阻塞
	c.Status(http.StatusOK)
	
	writeStart := time.Now()
	writer := c.Writer
	
	// 分块写入（每次1MB）
	chunkSize := 1024 * 1024 // 1MB
	totalWritten := 0
	
	for totalWritten < len(data) {
		end := totalWritten + chunkSize
		if end > len(data) {
			end = len(data)
		}
		
		n, err := writer.Write(data[totalWritten:end])
		if err != nil {
			log.Printf("❌ [分片API] 写入失败: RequestID=%s, Chunk=%d, Error=%v",
				requestID[:8]+"...", chunkIndex, err)
			return
		}
		
		totalWritten += n
		
		// 🔥 立即刷新缓冲区，不等待
		if flusher, ok := writer.(http.Flusher); ok {
			flusher.Flush()
		}
	}
	
	writeDuration := time.Since(writeStart)
	totalDuration := time.Since(startTime)
	
	log.Printf("✅ [分片API] 完成: RequestID=%s, Chunk=%d, Size=%.2f MB, 读取=%.3fs, 写入=%.3fs, 总计=%.3fs",
		requestID[:8]+"...", chunkIndex, float64(len(data))/(1024*1024),
		readDuration.Seconds(), writeDuration.Seconds(), totalDuration.Seconds())
}

// GetMeta 获取上传元数据（不包含Body）
// GET /api/upload/cache/:requestID/meta
func (h *UploadCacheHandler) GetMeta(c *gin.Context) {
	requestID := c.Param("requestID")

	// 从缓存获取
	upload, err := h.cacheManager.Get(requestID)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
		return
	}

	// 返回元数据
	c.JSON(http.StatusOK, gin.H{
		"request_id":     upload.RequestID,
		"tunnel_id":      upload.TunnelID,
		"method":         upload.Method,
		"path":           upload.Path,
		"headers":        upload.Headers,
		"content_type":   upload.ContentType,
		"content_length": upload.ContentLength,
		"is_chunked":     upload.IsChunked,
		"is_large_file":  upload.IsLargeFile,
		"chunk_size":     upload.ChunkSize,
		"total_chunks":   upload.TotalChunks,
		"created_at":     upload.CreatedAt,
		"expires_at":     upload.ExpiresAt,
	})
}
